package module.StoreService.Impl;

import common.model.Entity.StoreEntity.Category;
import dao.StoreDao.CategoryDao;
import dao.impl.StoreDaoImpl.CategoryDaoImpl;
import module.StoreService.CategoryService;
import network.protocol.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Optional;

/**
 * {@code CategoryServiceImpl} 是 {@link CategoryService} 的实现类，
 * 提供与分类（Category）相关的业务逻辑操作。
 * <p>
 * 主要功能包括：
 * <ul>
 *     <li>根据 ID 或名称查询分类</li>
 *     <li>获取所有分类或指定父分类下的子分类</li>
 *     <li>创建、更新、删除分类（逻辑删除）</li>
 *     <li>统计分类数量、检查分类是否存在</li>
 *     <li>检查分类名称是否存在、是否存在子分类</li>
 * </ul>
 * <p>
 * 实现逻辑通过 {@link CategoryDao} 与数据库交互，
 * 并使用 {@link Response} 封装统一的返回结果。
 * <p>
 * 类内部采用单例模式，请通过 {@link #getInstance()} 获取实例。
 */
public class CategoryServiceImpl implements CategoryService {
    private static final Logger logger = LoggerFactory.getLogger(CategoryServiceImpl.class);
    private final CategoryDao categoryDao = new CategoryDaoImpl();
    private static final CategoryServiceImpl INSTANCE = new CategoryServiceImpl();

    /**
     * 私有构造函数，防止外部直接实例化。
     */
    private CategoryServiceImpl() {}

    /**
     * 获取 {@code CategoryServiceImpl} 的单例对象。
     *
     * @return 单例实例
     */
    public static CategoryServiceImpl getInstance() {
        return INSTANCE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Optional<Category>> getCategoryById(long id) {
        try {
            Optional<Category> category = categoryDao.findById(id);
            return Response.success(category);
        } catch (Exception e) {
            logger.error("获取分类失败: id={}", id, e);
            return Response.error("获取分类失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Optional<Object>> getCategoriesByName(String name) {
        try {
            Optional<Object> categories = Optional.ofNullable(categoryDao.findByName(name));
            return Response.success(categories);
        } catch (Exception e) {
            logger.error("根据名称获取分类失败: name={}", name, e);
            return Response.error("根据名称获取分类失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<List<Category>> getAllCategories() {
        try {
            List<Category> categories = categoryDao.findAll();
            return Response.success(categories);
        } catch (Exception e) {
            logger.error("获取所有分类失败", e);
            return Response.error("获取所有分类失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<List<Category>> getCategoriesByParentId(long parentId) {
        try {
            List<Category> categories = categoryDao.findByParent(parentId);
            return Response.success(categories);
        } catch (Exception e) {
            logger.error("根据父分类ID获取子分类失败: parentId={}", parentId, e);
            return Response.error("根据父分类ID获取子分类失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> createCategory(Category category) {
        try {
            // 检查分类名称是否已存在
            Optional<Object> existing = Optional.ofNullable(categoryDao.findByName(category.getName()));
            if (existing.isPresent()) {
                logger.warn("创建分类失败: 分类名称 '{}' 已存在", category.getName());
                return Response.error("分类名称已存在");
            }
            boolean result = categoryDao.save(category);
            return result ? Response.success(true) : Response.error("创建分类失败");
        } catch (Exception e) {
            logger.error("创建分类失败: {}", category.getName(), e);
            return Response.error("创建分类失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> updateCategory(Category category) {
        try {
            // 确保分类存在
            if (categoryDao.findById(category.getId()).isEmpty()) {
                logger.warn("更新分类失败: 未找到ID为 {} 的分类", category.getId());
                return Response.error("未找到指定分类");
            }

            boolean result = categoryDao.update(category);
            return result ? Response.success(true) : Response.error("更新分类失败");
        } catch (Exception e) {
            logger.error("更新分类失败: id={}", category.getId(), e);
            return Response.error("更新分类失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> deleteCategory(long id) {
        try {
            // 确保分类存在
            Optional<Category> categoryOpt = categoryDao.findById(id);
            if (categoryOpt.isEmpty()) {
                logger.warn("删除分类失败: 未找到ID为 {} 的分类", id);
                return Response.error("未找到指定分类");
            }

            // 检查是否有子分类
            Response<Boolean> hasChildrenResponse = hasChildCategories(id);
            if (hasChildrenResponse.isSuccess() && Boolean.TRUE.equals(hasChildrenResponse.getData())) {
                logger.warn("删除分类失败: 分类ID {} 下有子分类，无法删除", id);
                return Response.error("该分类下有子分类，无法删除");
            }

            boolean result = categoryDao.deleteById(id);
            return result ? Response.success(true) : Response.error("删除分类失败");
        } catch (Exception e) {
            logger.error("删除分类失败: id={}", id, e);
            return Response.error("删除分类失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Long> getCategoryCount() {
        try {
            long count = categoryDao.count();
            return Response.success(count);
        } catch (Exception e) {
            logger.error("获取分类总数失败", e);
            return Response.error("获取分类总数失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> categoryExists(long id) {
        try {
            boolean exists = categoryDao.findById(id).isPresent();
            return Response.success(exists);
        } catch (Exception e) {
            logger.error("检查分类是否存在失败: id={}", id, e);
            return Response.error("检查分类是否存在失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> categoryNameExists(String name) {
        try {
            Optional<Object> categories = Optional.ofNullable(categoryDao.findByName(name));
            boolean exists = categories.isPresent();
            return Response.success(exists);
        } catch (Exception e) {
            logger.error("检查分类名称是否存在失败: name={}", name, e);
            return Response.error("检查分类名称是否存在失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> hasChildCategories(long parentId) {
        try {
            List<Category> childCategories = categoryDao.findByParent(parentId);
            boolean hasChildren = !childCategories.isEmpty();
            return Response.success(hasChildren);
        } catch (Exception e) {
            logger.error("检查是否有子分类失败: parentId={}", parentId, e);
            return Response.error("检查是否有子分类失败: " + e.getMessage());
        }
    }
}
